package com.sl.aoptest

import android.util.Log
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.*

/**
 * author： suliang
 * 2022/9/26 17:56
 * describe : 织入类
 *  MainActivity通过 javac 编译 -> .class文件
 *  TimeAspect 通过 ajc 编译 -> .class 文件
 *
 *  1、声明织入类，注解@Aspect ，通过 ajc 编译
 *  2、声明切入点。注解PointCut
 */
@Aspect
open class TimeAspect {
    //切入点，使用aspectJ的通配符语法
    // 关键字： execution(得到这个切入点的方法)   call(只是调用切入点的方法)
    // 返回参数 '*' 字符，任意参数，任意类型
    // 参数 '..' 有参，无参，多参都可以
    //该注解必须放在一个方法上
//    @Pointcut("execution(* com.sl.aoptest.MainActivity.getTime(..))")
//    @Pointcut("execution(* getTime(..))")
    @Pointcut("execution(@ExecuteTime * * (..))")
    private fun getTimes(){}

    //只指定实现了MainActivity的getTime（）的方法，指向固定的方法
//    @Pointcut("execution(* com.sl.aoptest.MainActivity.getTime(..))")
    // 指定所有的 getTime(..) 方法
//    @Pointcut("execution(* getTime(..))")
    //注解 这个注解标记的任何返回参数 任何方法 任何参数
//    @Pointcut("execution(@ExecuteTime * * (..))")

//    java.util.concurrent.ExecutionException: org.gradle.api.GradleException: circular advice precedence: can't determine precedence between two or more pieces of advice that apply to the same join point: method-execution(void com.sl.aoptest.MainActivity.getTime())
//    @Before("getTimes()")
//    fun timeBefore(){}
//
//    @After("getTimes()")
//    fun timeAfter(){}

    // 将切入点方法交给advice，执行这个方法
    // 获取getTimes方法，下面方法接收一个参数，可以获取getTimes方法
    @Around("getTimes()")
    open fun invokeGetTime(proceedingJoinPoint: ProceedingJoinPoint){
        Log.e("xxxxx","开始执行")
        val start = System.currentTimeMillis()
        try {
            //执行切入点方法
            proceedingJoinPoint.proceed()
        } catch (e: Exception) {
            e.printStackTrace()
        }

        val endTime = System.currentTimeMillis()

        Log.e("xxxxx","执行耗时 --》 " + (endTime - start) )
    }


}